class Queue {
  constructor() {
    /** count属性来帮助我们控制队列的大小 */
    this.count = 0;
    /** 帮助我们追踪第一个元素 */
    this.lowestCount = 0;
    /** 为了写出一个在获取元素时更高效的数据结构 */
    this.items = {};
  }

  /* 向队列尾部添加一个（或多个）新的项。 */
  enqueue(element) {
    this.count++;
    this.items[this.count] = element;
  }

  /* 移除队列的第一项（即排在队列最前面的项）并返回被移除的元素。 */
  dequeue() {
    if (this.isEmpty()) {
      return undefined;
    }
    this.lowestCount++;
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    return result;
  }

  /*
   * 返回队列中第一个元素——最先被添加，也将是最先被移除的元素。队列不做任何变动（不移除元素，只返回元素信息——与Stack类的peek方法非常类似）。
   * 该方法在其他语言中也可以叫作front方法。
   */
  peek() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items[this.lowestCount + 1];
  }

  /* 如果队列中不包含任何元素，返回true，否则返回false。 */
  isEmpty() {
    return this.count === this.lowestCount;
  }

  /* 返回队列包含的元素个数，与数组的length属性类似。 */
  size() {
    return this.count - this.lowestCount;
  }

  clear() {
    this.items = {};
    this.count = 0;
    this.lowestCount = 0;
  }

  toString() {
    if (this.isEmpty()) {
      return '';
    }

    let objString = '';
    for (let i = this.lowestCount + 1; i <= this.count; i++) {
      objString += `${i}: ${this.items[i]} , `;
    }
    return objString;
  }
}

const queue = new Queue();
console.log(queue.isEmpty());
queue.enqueue(8);
queue.enqueue(5);
queue.enqueue(1);
console.log('toString', queue.toString());
console.log('size', queue.size());
console.log('peek', queue.peek());
console.log('dequeue', queue.dequeue());
console.log('size', queue.size());
console.log('peek', queue.peek());
